package lol.oxguy3.android.mcmc;

import java.util.HashMap;

import net.minecraft.src.Packet3Chat;
import net.minecraft.src.ThreadConnectToServer;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Typeface;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.CharacterStyle;
import android.text.style.ForegroundColorSpan;
import android.text.style.StrikethroughSpan;
import android.text.style.StyleSpan;
import android.text.style.UnderlineSpan;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.view.View;

public class ServerChatActivity extends Activity implements View.OnClickListener {
	Context cxt;
	SharedPreferences settings;
	
	LinearLayout chatview;
	Button sendbtn;
	EditText chatfield;
	

    /** A reference to the NetClientHandler. */
	private NetMcmcHandler clientHandler;

    /** True if the connection attempt has been cancelled. */
    private boolean cancelled;
    
	
	public static final String SPCHAR = "\247"; /** the character that always makes up the first half of a color code */
	public static final String REGEX_SPCODES = SPCHAR + "{1}[[A-F][a-f][K-O][k-o][0-9]Rr]{1}"; /** the regex to match a full color code */
	public static HashMap<String,CharacterStyle> formatchars = new HashMap<String,CharacterStyle>();
	static {
		formatchars.put("0", new ForegroundColorSpan(0xff000000)); /** black */
		formatchars.put("1", new ForegroundColorSpan(0xff0000aa)); /** dark blue */
		formatchars.put("2", new ForegroundColorSpan(0xff00aa00)); /** dark green */
		formatchars.put("3", new ForegroundColorSpan(0xff00aaaa)); /** dark cyan */
		formatchars.put("4", new ForegroundColorSpan(0xffaa0000)); /** dark red */
		formatchars.put("5", new ForegroundColorSpan(0xffaa00aa)); /** purple */
		formatchars.put("6", new ForegroundColorSpan(0xffffaa00)); /** gold */
		formatchars.put("7", new ForegroundColorSpan(0xffaaaaaa)); /** gray */
		formatchars.put("8", new ForegroundColorSpan(0xff555555)); /** dark gray */
		formatchars.put("9", new ForegroundColorSpan(0xff5555ff)); /** blue */
		formatchars.put("a", new ForegroundColorSpan(0xff55ff55)); /** bright green */
		formatchars.put("b", new ForegroundColorSpan(0xff55ffff)); /** cyan */
		formatchars.put("c", new ForegroundColorSpan(0xffff5555)); /** red */
		formatchars.put("d", new ForegroundColorSpan(0xffff55ff)); /** pink */
		formatchars.put("e", new ForegroundColorSpan(0xffffff55)); /** yellow */
		formatchars.put("f", new ForegroundColorSpan(0xffffffff)); /** white */
		
		formatchars.put("k", new StrikethroughSpan()); /** random */ //TODO this is a completely BS implementation, needs to actually be random not strikethrough
		formatchars.put("l", new StyleSpan(Typeface.BOLD)); /** bold */
		formatchars.put("m", new StrikethroughSpan()); /** strikethrough */
		formatchars.put("n", new UnderlineSpan()); /** underlined */
		formatchars.put("o", new StyleSpan(Typeface.ITALIC)); /** italic */
		formatchars.put("r", new StyleSpan(Typeface.NORMAL)); /** plain */
		
		/** easiest way of dealing with capital letters */
		formatchars.put("A", formatchars.get("a")); /** bright green */
		formatchars.put("B", formatchars.get("b")); /** cyan */
		formatchars.put("C", formatchars.get("c")); /** red */
		formatchars.put("D", formatchars.get("d")); /** pink */
		formatchars.put("E", formatchars.get("e")); /** yellow */
		formatchars.put("F", formatchars.get("f")); /** white */
		formatchars.put("K", formatchars.get("k")); /** random */
		formatchars.put("L", formatchars.get("l")); /** bold */
		formatchars.put("M", formatchars.get("m")); /** strikethrough */
		formatchars.put("N", formatchars.get("n")); /** underlined */
		formatchars.put("O", formatchars.get("o")); /** italic */
		formatchars.put("R", formatchars.get("r")); /** plain */
		
		//TODO Need to be able to stack Bold and Italics to make an instance: StyleSpan(Typeface.BOLD_ITALIC)
	}
	
	public Bundle serverinfo;
	public SharedPreferences sprefs;
	
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
        setContentView(R.layout.serverchat);

		cxt = this;
        settings = PreferenceManager.getDefaultSharedPreferences(this);
		

        chatview = (LinearLayout) findViewById(R.id.linearLayoutInGameChat);
        chatfield = (EditText) findViewById(R.id.editTextInGameChat);
        sendbtn = (Button) findViewById(R.id.buttonSendChat);
        
        sendbtn.setOnClickListener(this);
        

        serverinfo = getIntent().getExtras();
        sprefs = cxt.getSharedPreferences("login", MODE_PRIVATE);
        

        cancelled = false;
        String connectingMessage = (new StringBuilder()).append("Connecting to ").append(serverinfo.getString("address")).append(", ").append(serverinfo.getInt("port")).toString();
        System.out.println(connectingMessage);
        
        //addChatMessage(SPCHAR+"4red"+SPCHAR+"1blue"+SPCHAR+"2green");
        addChatMessage(connectingMessage);
        (new ThreadConnectToServer(this, cxt, serverinfo.getString("address"), serverinfo.getInt("port"))).start();
	}
	
	
	/**
	 * Adds a message to the chat ScrollView
	 * 
	 * @param s the message
	 */
	public void addChatMessage(String s) {
		
		String dirty = s; /** the raw string with color codes */
		String clean = s.replaceAll(REGEX_SPCODES, ""); /** the string without color codes */
		
		SpannableString spanstr = new SpannableString((CharSequence)clean); /** a formattable version of 'clean' */
		
		int ind;
		CharacterStyle span;
		
		while((ind = dirty.indexOf(SPCHAR)) != -1) {
			span = formatchars.get(dirty.substring(ind+1, ind+2));
			if (span != null) {
				
				/** add the span to the formatted string */
				spanstr.setSpan(span, ind, spanstr.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
				
				/** remove the color code from 'dirty' so that s stays in sync with 'clean' and 'spanstr' */
				String[] split = dirty.split(REGEX_SPCODES, 2);
				dirty = split[0].concat(split[1]);
				
			} else {
				/** replace the instance of SPCHAR with an ampersand so that 'dirty' stays in sync with 'clean'/'spanstr', but doesn't get stuck in an infinite loop of checking the same invalid color code over and over */
				String[] split = dirty.split(SPCHAR, 2);
				dirty = split[0].concat("&"+split[1]);
			}
		}
		
		TextView tv = new TextView(cxt);
		tv.setPadding(0, 0, 0, 3);
		tv.setText(spanstr);
		chatview.addView(tv);
	}
	


    /**
     * Sets the NetClientHandler.
     */
    public static NetMcmcHandler setNetClientHandler(ServerChatActivity par0GuiConnecting, NetMcmcHandler par1NetClientHandler)
    {
        return par0GuiConnecting.clientHandler = par1NetClientHandler;
    }

    /**
     * Returns true if the connection attempt has been cancelled, false otherwise.
     */
    public static boolean isCancelled(ServerChatActivity par0GuiConnecting)
    {
        return par0GuiConnecting.cancelled;
    }

    /**
     * Gets the NetClientHandler.
     */
    public static NetMcmcHandler getNetClientHandler(ServerChatActivity par0GuiConnecting)
    {
        return par0GuiConnecting.clientHandler;
    }


	public void onClick(View v) {
		if (v.equals(sendbtn)) {
			clientHandler.addToSendQueue(new Packet3Chat(chatfield.getText().toString()));
		} else {
			addChatMessage(SPCHAR+"4Unknown button pressed!");
		}
	}
}
